#pragma once

#ifdef WIN32
#ifdef NETDECT_EXPORTS
#define NETDECT_API __declspec(dllexport)
#else
#define NETDECT_API __declspec(dllimport)
#endif
#else
#define NETDECT_API
#endif

#ifdef __cplusplus
#   define NETDECT_CAPI          extern "C" NETDECT_API
#else
#   define NETDECT_CAPI			 NETDECT_API
#endif

#include <string>
#include <set>
#include <vector>

class INtdConn;

class INtdGroup
{
public:
	virtual void SetRateLimit(int rate) = 0;
	virtual int GetRateLimit() = 0;

	virtual void GetNtdConns(std::set<INtdConn*>& ntdSet) = 0;
	virtual void AddNtdConn(const INtdConn * conn) = 0;
	virtual void RemoveNtdConn(const INtdConn * conn) = 0;
};

class INtdConn
{
public:
	enum CONN_TPYE{ CONN_TCP, CONN_UDP };
	enum CONN_PRI{ PRI_LOW, PRI_MID, PRI_HIG };
	struct RouteInfo{
		std::string ip;
		int rtt;
	};

	virtual void SetRateLimit(int ratelimit) = 0;
	virtual void SetPacketSize(int size) = 0;
	virtual void SetPriority(CONN_PRI pri) = 0;
	virtual void SetGroup(INtdGroup* g) = 0;

	virtual int GetConnID() = 0;
	virtual INtdConn::CONN_TPYE GetConnType() = 0;
	virtual INtdConn::CONN_PRI GetConnPriority() = 0;
	virtual int GetRoute(std::vector<INtdConn::RouteInfo>& ipList) = 0;

	virtual int GetLocalSendingRate() = 0;
	virtual int GetRemoteReceivingRate() = 0;

	virtual INtdGroup* GetGroup() = 0;
};

class INtdConnMgr
{
public:
	virtual INtdConn * Create(std::string ipstr, 
		                          int port, 
								  INtdConn::CONN_TPYE t) = 0;

	virtual void Destory(INtdConn * pClient) = 0;
};

class IGroupMgr
{
public:
	virtual INtdGroup * Create();
	virtual void Destory(INtdGroup * g);
	virtual INtdGroup * MergeGroup(INtdGroup * g1, INtdGroup * g2);
	virtual void SplitGroup(std::set<INtdConn*> ntdSet1, std::set<INtdConn*> ntdSet2, 
		                    INtdGroup ** g1, INtdGroup ** g2);
};

NETDECT_CAPI INtdConn * CreateNtdConnMgr();
NETDECT_CAPI void DestoryNtdConnMgr(INtdConn * pClient);

NETDECT_CAPI IGroupMgr * CreateNtdGroup();
NETDECT_CAPI void DestoryNtdGroup(IGroupMgr * pServer);